import * as THREE from 'https://cdn.skypack.dev/three@0.110.0';
// import * as THREE from './three.module.js';
// import * as THREE from 'three';
import { Line2 } from './Line2.js';
import { LineMaterial } from './LineMaterial.js';
import { LineGeometry } from './LineGeometry.js';
import { EffectComposer } from 'https://unpkg.com/three@0.110.0/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'https://unpkg.com/three@0.110.0/examples/jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'https://unpkg.com/three@0.110.0/examples/jsm/postprocessing/UnrealBloomPass.js';

var __mapcenter__ = [116.582, 35.415];
mapboxgl.accessToken = 'pk.eyJ1IjoiaG91eGlleXUiLCJhIjoiY2pldjE5amU3NndzeDM5bzd5bm9ncDgycyJ9.j1F-Lgid3L5k2Abm8_xTeQ';
var mapboxStyle = {
    "version": 8,
    "sprite": "mapbox://sprites/mapbox/dark-v10",
    "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
    // "sources": {
    //     "mapbox": {
    //         "type": "vector",
    //         "url": "mapbox://mapbox.mapbox-streets-v8"
    //     },
    // },
    "sources": {
        "raster-tiles": {
            "type": "raster",
            'tiles': [
                "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=067998e486ea7ea61c91442ec719e8b3",
                // "https://webrd03.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8"
                // "https://mt1.google.cn/maps/vt?lyrs=s%40721&hl=zh-CN&gl=CN&x={x}&y={y}&z={z}"
                // "http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
                // 'http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png'
                // 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            ],
            "tileSize": 256
        }
    },
    "layers": [
        {
            "id": "simple-tiles",
            "type": "raster",
            "source": "raster-tiles",
            "minzoom": 0,
            "maxzoom": 18
        },
        // {
        //     "id": "bk",
        //     "type": "background",
        //     "paint": {
        //         "background-color": "rgba(100,100,100,1)"
        //     },
        //     "layout": {
        //         "visibility": "visible"
        //     },
        //     "metadata": {
        //         "mapbox:group": "92ca48f13df25"
        //     }
        // },
    ]
}

// var mapboxgl_style ='mapbox://styles/houxieyu/cjuzixmlt0jun1fntbnkttjy3';
var mapboxgl_style = 'mapbox://styles/mapbox/dark-v10';
var tb;
function addTB(mapd, gl) {
    tb = new Threebox(
        mapd,
        gl,
        { defaultLights: true }
    );
    var sphere = tb.sphere({ radius: 1, color: 'red', material: 'MeshStandardMaterial' })
        .setCoords(__mapcenter__.concat([500]));
    // add sphere to the scene
    tb.add(sphere);
}
const linetype = 0;//0=normal 1=fat
// var map = myChart.getModel().getComponent('mapbox3D').getMapbox();
var map = new mapboxgl.Map({
    container: 'map',
    style: mapboxgl_style,
    zoom: 18,
    center: __mapcenter__,
    pitch: 60,
    antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});

// var THREE = window.THREE;
function drawLine(points) {
    var mts = [new THREE.LineBasicMaterial({
        vertexColors: true
    }), new LineMaterial({
        linewidth: 0.005, // in pixels
        vertexColors: true//THREE.VertexColors,
    }),]
    var material = mts[linetype]
    var geos = [new THREE.Geometry(),
    new LineGeometry()
    ]
    var geometry = geos[linetype]

    var positions = [];
    var colors = [];

    points.forEach((d, i) => {
        const { x, y, z } = d;
        var c = new THREE.Color(i ? i : 1, i ? 0 : 1, i ? 0 : 1);
        if (linetype == 0) {
            geometry.vertices.push(new THREE.Vector3(x, y, z));
            // geometry.colors.push( new THREE.Color('rgb('+(i==1?0:255)+',0,'+(i==0?0:255)+')'))
            geometry.colors.push(c)
        }
        else {
            positions.push(x, y, z);
            colors.push(c.r, c.g, c.b)
        }

    });
    if (linetype == 1) {
        geometry.setPositions(positions);
        geometry.setColors(colors);
    }
    // console.log(colors,geometry.colors)
    var linegeo = [
        new THREE.Line(geometry, material),
        new Line2(geometry, material)
    ]
    return linegeo[linetype];
}
$.ajaxSettings.async = false;
var linesdata;
// $.getJSON(encodeURI('http://124.133.27.90:6082/main/getGEOJsonByFilter'),
//     {
//         filter: "1=1",//"对象类型='一套表单位'" ,
//         fields: '名称,对象类型,经度,纬度',
//         limit: 100
//     },
$.getJSON('jp4data.json',
    function (res) {
        linesdata = res;
    });
// configuration of the custom layer for a 3D model per the CustomLayerInterface
function initThree(_this, mapd) {
    _this.camera = new THREE.Camera();
    _this.scene = new THREE.Scene();
    // create two three.js lights to illuminate the model
    // var directionalLight = new THREE.DirectionalLight(0xffffff);
    // directionalLight.position.set(0, -70, 100).normalize();
    // this.scene.add(directionalLight);

    // var directionalLight2 = new THREE.DirectionalLight(0xffffff);
    // directionalLight2.position.set(0, 70, 100).normalize();
    // this.scene.add(directionalLight2);
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
    _this.scene.add(directionalLight);
    _this.map = mapd;
}
var lineGroup;
var mbpt = lnglatToMector(__mapcenter__,0);
var threescale = mbpt.meterInMercatorCoordinateUnits();
var customLayer = {
    id: '3d-model',
    type: 'custom',
    renderingMode: '3d',
    onAdd: function (mapd, gl) {
        initThree(this, mapd);
        // addTB(mapd, gl);
        //绘制光源
        addLight(this.scene);
        //绘制飞线
        drawLines(this.scene);
        //绘制建筑物
        this.drawBuildings();
        // this.addbuildings();
        this.renderer = new THREE.WebGLRenderer({
            canvas: mapd.getCanvas(),
            antialias: true,
            alpha: true,
            context: gl,
            antialias: true
        });

        this.renderer.autoClear = false;

        const renderScene = new RenderPass( this.scene, this.camera );
				const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 5, 5, 5 );
				bloomPass.threshold = 0.3;
				bloomPass.strength = 2;
				bloomPass.radius = 0.6;

				this.composer = new EffectComposer( this.renderer );
				this.composer.addPass( renderScene );
				this.composer.addPass( bloomPass );
    },
     drawBuildings(){
        // 把经纬度转换成x,y,z 坐标
        builds.forEach(d => {
          d.vector3 = [];
          d.geometry.coordinates.forEach((coordinates, i) => {
            d.vector3[i] = [];
            coordinates.forEach((c, j) => {
              if (c[0] instanceof Array) {
                d.vector3[i][j] = [];
                c.forEach(cinner => {
                  let cp = lnglatToLocal(cinner,0);
                  d.vector3[i][j].push(cp);
                });
              } else {
                let cp = lnglatToLocal(c,0);
                d.vector3[i].push(cp);
              }
            });
          });
        });
        console.log(builds)
        // 绘制地图模型
        const group = new THREE.Group();
        const lineGroup = new THREE.Group();
        builds.forEach(d => {
          const g = new THREE.Group(); // 用于存放每个地图模块。||省份
          g.data = d;
          d.vector3.forEach(points => {
            // 多个面
            if (points[0][0] instanceof Array) {
              points.forEach(p => {
                if(p.length>3){
                const mesh = drawModel(p);
              //   const lineMesh = drawLine(p);
                // lineGroup.add(lineMesh);
                mesh && g.add(mesh);
                }
              });
            } else {
                if(points[0].length>3){
              // 单个面
              const mesh = drawModel(points[0]);
              // const lineMesh = drawLine(points);
              // lineGroup.add(lineMesh);
              mesh && g.add(mesh);
                }
            }
          });
          group.add(g);
        });
        this.group = group; // 丢到全局去
      //   const lineGroupBottom = lineGroup.clone();
      //   lineGroupBottom.position.z = -2;
      //   this.scene.add(lineGroup);
      //   this.scene.add(lineGroupBottom);
        this.scene.add(group);
  },
  addbuildings(){
    let formatPath = [];
    for (let i = 0; i < builds.length; i++) {
        if (builds[i].geometry && builds[i].geometry.coordinates[0]) {
            let polygons = builds[i].geometry && builds[i].geometry.coordinates[0][0];
            let height = builds[i].properties.height;
            let path = [];
            for (let j = 0, len = polygons.length; j < len; j++) {
                let coord = polygons[j];
                path.push(new THREE.Vector3(coord[0], coord[1], height));
            }
            formatPath.push(path);
        }
    }
    // let path = params.data
    let path = formatPath;
    let bottomColor = '#ff0000';
    let topColor =  '#ffff00';
    let opacity = 1;
  
    let paths = [];
    for (let i = 0; i < path.length; i++) {
      const unitPath = path[i]
      let formatPath = [];
      formatPath = unitPath.map((vec) => {
        let position = lnglatToLocal([vec.x, vec.y], vec.z);
        return new THREE.Vector3(position.x, position.y, position.z)
      });
      paths.push(formatPath)
    }
  
    const mergePositions = []
    const mergeUvs = []
    const mergeUvs2 = []
  
    for (let i = 0; i < paths.length; i++) {
      const _path = paths[i]
  
      const xys1 = []
      for (let j = 0; j < _path.length; j++) {
        const point = _path[j]
        xys1.push([point.x, point.y])
      }
  
      const xys = flatten(xys1)
      // 获得每一段的长度
      const xySegLength = []
      for (let ii = 0, ij = 0; ii < xys.length - 2; ii += 2, ij++) {
        if (ii === 0) {
          xySegLength[0] = Math.sqrt((xys[2] - xys[0]) * (xys[2] - xys[0]) + (xys[3] - xys[1]) * (xys[3] - xys[1]))
        } else {
          xySegLength[ij] = xySegLength[ij - 1] + Math.sqrt((xys[ii + 2] - xys[ii]) * (xys[ii + 2] - xys[ii]) + (xys[ii + 3] - xys[ii + 1]) * (xys[ii + 3] - xys[ii + 1]))
        }
      }
  
      /*
          uv  index(uv.x, uv.y)
          1(0, 1)               2(1, 1) 5(1, 1)
          0(0, 0) 4(0, 0)       3(0, 1)
          一个矩形面 由两个三角面组成，总共六个顶点按照 index先后顺序设置
      */
      const positions = []
      const uvs = []
      const uvs2 = []
      const wholeLength = xySegLength[xySegLength.length - 1]
      const maxHeight = 40
      for (let ii = 0, j = positions.length, t = uvs.length, k = uvs2.length; ii < _path.length - 1; ii++) {
        const left = _path[ii]
        const right = _path[ii + 1]
        const segLength = xySegLength[ii]
  
        positions[j++] = left.x
        positions[j++] = left.y
        positions[j++] = 0
        uvs[t++] = ii === 0 ? 0 : xySegLength[ii - 1] / wholeLength
        uvs[t++] = 0
        uvs2[k++] = _path.length - 1
        uvs2[k++] = left.z / maxHeight
  
        positions[j++] = left.x
        positions[j++] = left.y
        positions[j++] = left.z
        uvs[t++] = ii === 0 ? 0 : xySegLength[ii - 1] / wholeLength
        uvs[t++] = left.z / maxHeight
        uvs2[k++] = _path.length - 1
        uvs2[k++] = left.z / maxHeight
  
        positions[j++] = right.x
        positions[j++] = right.y
        positions[j++] = right.z
        uvs[t++] = segLength / wholeLength
        uvs[t++] = right.z / maxHeight
        uvs2[k++] = _path.length - 1
        uvs2[k++] = right.z / maxHeight
  
        positions[j++] = right.x
        positions[j++] = right.y
        positions[j++] = 0
        uvs[t++] = segLength / wholeLength
        uvs[t++] = 0
        uvs2[k++] = _path.length - 1
        uvs2[k++] = left.z / maxHeight
  
        positions[j++] = left.x
        positions[j++] = left.y
        positions[j++] = 0
        uvs[t++] = ii === 0 ? 0 : xySegLength[ii - 1] / wholeLength
        uvs[t++] = 0
        uvs2[k++] = _path.length - 1
        uvs2[k++] = left.z / maxHeight
  
        positions[j++] = right.x
        positions[j++] = right.y
        positions[j++] = right.z
        uvs[t++] = segLength / wholeLength
        uvs[t++] = right.z / maxHeight
        uvs2[k++] = _path.length - 1
        uvs2[k++] = right.z / maxHeight
      }
  
      mergePositions.push(positions)
      mergeUvs.push(uvs)
      mergeUvs2.push(uvs2)
    }
  
    const _topGeometry = new THREE.Geometry()
    for (let i = 0; i < paths.length; i++) {
      const _path2 = paths[i]
  
      let unitGeo = new THREE.Geometry()
      for (let j = 0; j < _path2.length; j++) {
        unitGeo.vertices.push(new THREE.Vector3(_path2[j].x, _path2[j].y, _path2[j].z))
        if (j < _path2.length - 2) {
          unitGeo.faces.push(new THREE.Face3(0, j + 1, j + 2))
        }
      }
      unitGeo.verticesNeedUpdate = true
      unitGeo.computeFaceNormals()
      unitGeo.computeVertexNormals()
  
      let unitMesh = new THREE.Mesh(unitGeo, new THREE.MeshBasicMaterial({ color: 0xffffff }))
      unitMesh.updateMatrix()
      _topGeometry.merge(unitMesh.geometry, unitMesh.matrix)
      unitMesh.geometry.dispose()
      unitMesh.material.dispose()
      unitMesh = null
    }
    _topGeometry.verticesNeedUpdate = true
    _topGeometry.computeFaceNormals()
    _topGeometry.computeVertexNormals()
    const topBufferGeometry = new THREE.BufferGeometry().fromGeometry(_topGeometry)
    const topPositionsBuffer = topBufferGeometry.attributes.position.array
  
    const geometry = new THREE.Geometry()
    for (let i = 0; i < mergePositions.length; i++) {
      const _geometry = new THREE.BufferGeometry()
      _geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(mergePositions[i]), 3))
      _geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(mergeUvs[i]), 2))
      _geometry.setAttribute('uv2', new THREE.BufferAttribute(new Float32Array(mergeUvs2[i]), 2))
      let unitMesh = new THREE.Mesh(_geometry, new THREE.MeshBasicMaterial({ color: 0xffffff }))
      const _geo = new THREE.Geometry().fromBufferGeometry(unitMesh.geometry)
      unitMesh.updateMatrix()
      geometry.merge(_geo, unitMesh.matrix)
  
      _geometry.dispose()
      unitMesh.geometry.dispose()
      unitMesh.material.dispose()
      unitMesh = null
      _geo.dispose()
    }
    const bufferGeometry = new THREE.BufferGeometry().fromGeometry(geometry)
    const positionsBuffer = bufferGeometry.attributes.position.array
    const uvsBuffer = bufferGeometry.attributes.uv.array
    const uvs2Buffer = bufferGeometry.attributes.uv2.array
  
    const sideGeometry = new THREE.BufferGeometry()
    sideGeometry.setAttribute('position', new THREE.BufferAttribute(positionsBuffer, 3))
    sideGeometry.setAttribute('uv', new THREE.BufferAttribute(uvsBuffer, 2))
    sideGeometry.setAttribute('maxUv', new THREE.BufferAttribute(uvs2Buffer, 2))
  
    const topGeometry = new THREE.BufferGeometry()
    topGeometry.setAttribute('position', new THREE.BufferAttribute(topPositionsBuffer, 3))
    
    const material2 = new THREE.MeshBasicMaterial({
      color: new THREE.Color(topColor),
      depthWrite: true,
      // polygonOffsetFactor: 0,
      // polygonOffsetUnits: 1.0,
      blending: THREE.NoBlending,
      side: THREE.DoubleSide
    })
  
    let loader = new THREE.TextureLoader()
    let maps = []
    const map1 = loader.load('./img/building1.png')
    map1.wrapS = map1.wrapT = THREE.RepeatWrapping
    map1.generateMipmaps = false
    map1.magFilter = THREE.LinearFilter
    map1.minFilter = THREE.LinearFilter
    const map2 = loader.load('./img/building2.png')
    map1.wrapS = map1.wrapT = THREE.RepeatWrapping
    map2.generateMipmaps = false
    map2.magFilter = THREE.LinearFilter
    map2.minFilter = THREE.LinearFilter
    maps.push(map1)
    maps.push(map2)
  
    let uniforms = {
      bottomColor: { type: 'c', value: new THREE.Color(bottomColor) },
      topColor: { type: 'c', value: new THREE.Color(topColor) },
      opacity: { type: 'f', value: 1 },
      maps: { value: maps }
    }
  
    let vertex = `
      precision highp float;
      attribute vec2 maxUv;
      precision highp int;
      varying vec2 vUv;
      varying vec2 vUv2;
      void main() {
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vUv = uv;
        vUv2 = maxUv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      }`
    let fragment = `
      precision highp float;
      precision highp int;
      varying vec2 vUv;
      varying vec2 vUv2;
      uniform vec3 bottomColor;
      uniform vec3 topColor;
      uniform float opacity;
      uniform sampler2D maps[2];
  
      void main() {
        vec2 uv = vUv;
        vec2 uv2 = vUv2;
        vec2 uv3 = vUv;
        uv3.y *= (1. / uv2.y);
        uv3.x = fract(uv3.x * uv2.x);
        gl_FragColor = vec4(0.8,0.8,0.8,1.0);

        // if (uv2.y < 0.4) {
        //   gl_FragColor = texture2D(maps[0], uv3);
        // } else {
        //   gl_FragColor = texture2D(maps[1], uv3);
        // }
      }
    `
    let material = new THREE.ShaderMaterial({
      uniforms: uniforms,
      vertexShader: vertex,
      fragmentShader: fragment,
      // polygonOffsetFactor: 0,
      // polygonOffsetUnits: 1.0,
      blending: THREE.NormalBlending,
      depthWrite: true,
      side: THREE.DoubleSide
    })
    const building = new THREE.Mesh(sideGeometry, material)
    building.renderOrder = 20
    const top = new THREE.Mesh(topGeometry, material2)
    top.renderOrder = 21
  
    this.scene.add(building)
    this.scene.add(top)

    // return {
    //   side: building,
    //   top: top
    // }
  },
    render: function (gl, matrix) {
        updateLight();
        // tb.update();
        updateLines();
        var m = new THREE.Matrix4().fromArray(matrix);
        var l = new THREE.Matrix4()
            .makeTranslation(
                mbpt.x,
                mbpt.y,
                mbpt.z
            )
            .scale(
                new THREE.Vector3(
                    threescale,
                    -threescale,
                    threescale
                )
            );
        this.camera.projectionMatrix = m.multiply(l);
        // this.camera.projectionMatrix =new THREE.Matrix4().fromArray(matrix);

        // this.renderer.state.reset();
        this.renderer.render(this.scene, this.camera);
        // this.composer.render();
        this.map.triggerRepaint();
    }
};

function updateLines() {
    lineGroup.children.forEach(function (obj) {
        obj.scale.add(new THREE.Vector3(0, 0, 0.1))
        if (obj.scale.z > 2) {
            obj.scale.setZ(0.1)
        }
        //     // obj.material.color = new THREE.Color(Math.random(),Math.random(),Math.random());
        //     obj.rotation.x += 0.01;
        //     obj.rotation.y += 0.01;
    })
    // lineGroup.scale.add(new THREE.Vector3(0,0,0.1))
    // if(lineGroup.scale.z > 2){
    //     lineGroup.scale.setZ(0)
    // }
}
map.on('style.load', function () {
    // addMapboxExtrudeLayer();
    map.addLayer(customLayer);
});
// used to determine the switch point for the light animation
var invert = 1;
var phase = 0;
function updateLight() {
    // move the light simulation
    if (phase > 2 * Math.PI) {
        invert = invert * -1;
        phase -= 2 * Math.PI;
    } else {
        phase += 0.01;
    }
    sphereLightMesh.position.x = +(200 * (Math.sin(phase)));
    sphereLightMesh.position.y = +(400 * (Math.cos(phase)));
    // if (invert < 0) {
    //     var pivot = 1;
    //     sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;
    // }

    pointLight.position.copy(sphereLightMesh.position);
}
var pointColor, pointLight, sphereLight, sphereLightMaterial, sphereLightMesh
function addLight(scene) {
    scene.add(new THREE.AmbientLight(0xffffff));
    var sunlight = new THREE.DirectionalLight(0xffffff, 0.25);
    sunlight.position.set(0, 80000000, 100000000);
    sunlight.matrixWorldNeedsUpdate = true;
    scene.add(sunlight);

    pointColor = "#ccffcc";
    pointLight = new THREE.PointLight(pointColor);
    pointLight.distance = 0.1;
    scene.add(pointLight);

    sphereLight = new THREE.SphereBufferGeometry(10, 120, 120);
    sphereLightMaterial = new THREE.MeshStandardMaterial({ color: 0xac6c25 });
    sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
    // sphereLightMesh.castShadow = true;
    sphereLightMesh.position.set(0, 0, 100);
    sphereLightMesh.scale.set(1, 1, 1);

    // sphereLightMesh.position.set(pt.x, pt.y, pt.z);
    // sphereLightMesh.scale.set(threescale,threescale,threescale);
    scene.add(sphereLightMesh);
}
// var mapcenter = map.getCenter()
// setTimeout(() => {
//     map.flyTo({ center: [0, 0], zoom: 9 });

// }, 3000)
/**
  * @desc 经纬度转换成墨卡托投影
  * @param {array} 传入经纬度
  * @return array [x,y,z]
  */
function lnglatToMector(lnglat,height) {
    return mapboxgl.MercatorCoordinate.fromLngLat(
        lnglat,
        height
    );
}

function drawLines(scene) {
    lineGroup = new THREE.Group();
    linesdata.features.forEach(function (element, inx) {
        if (element.geometry.coordinates[0] == null) return;
        var basept = lnglatToLocal(element.geometry.coordinates,0);
        var toppt = lnglatToLocal(element.geometry.coordinates,500);
        // console.log(basept)
        var lineMesh = drawLine([basept, toppt]);
        lineMesh.scale.set(1, 1, Math.random() * 2);
        lineGroup.add(lineMesh);
    });
    scene.add(lineGroup);
}


// buildingjson.features.forEach(ft => {
//     ft.properties.ftcolor = '#CCCCFF';
// })

  /**
   * @desc 经纬度转换成墨卡托投影
   * @param {array} 传入经纬度
   * @return array [x,y,z]
   */
   function lnglatToMector0(lnglat) {
    // if (!this.projection) {
    //   this.projection = d3
    //     .geoMercator()
    //     .center([108.904496, 32.668849])
    //     .scale(80)
    //     .rotate(Math.PI / 4)
    //     .translate([0, 0]);
    // }
    // const [y, x] = this.projection([...lnglat]);
    // let z = 0;
    // return [x, y, z];
  }

/**
 * @desc 绘制地图模型 points 是一个二维数组 [[x,y], [x,y], [x,y]]
 */
 function drawModel(points) {
    const shape = new THREE.Shape();
    points.forEach((d, i) => {
        const {x, y} = d;
        if (i === 0) {
        shape.moveTo(x, y);
        } else if (i === points.length - 1) {
        shape.quadraticCurveTo(x, y, x, y);
        } else {
        shape.lineTo(x, y, x, y);
        }
    });

    const geometry = new THREE.ExtrudeGeometry(shape, {
        depth: -2,
        bevelEnabled: false
    });
    const material = new THREE.MeshBasicMaterial({
        color: 'red',
        transparent: false,
        opacity: 0.6,
        side: THREE.DoubleSide
    });
    const mesh = new THREE.Mesh(geometry, material);
    return mesh;
}


var shines = [];
// var colors = ['#FFCCCC', '#FFFF99', '#CCCCFF'];
var colors = ['#FF6666', '#FFFF00', '#0066CC'];

function addMapboxExtrudeLayer() {
    map.addSource("buildings", {
        type: "geojson",
        data: buildingjson,
        type: "geojson",
        // type: "vector",
        // "url": "mapbox://houxieyu.as833g2t",
    });
    map.addLayer({
        'id': '3dbuildings',
        'source': 'buildings',
        // 'source-layer': 'jiningbuildings-7kbdau',
        'type': 'fill-extrusion',
        'minzoom': 0,
        'paint': {
            'fill-extrusion-height': ["get", "height"],// ["*", 3, ["to-number",["get", "hegiht"]]],
            'fill-extrusion-color':
                // ["get", "ftcolor"]
                // ["case", ["to-boolean", ["feature-state", "cc"]], ["feature-state", "cc"], colors[2]]
                ["case", ["to-boolean", ["feature-state", "cc"]], ["case", ["feature-state", "shine"], ["feature-state", "cc"], colors[2]], colors[2]]
        }
    });
    // initShine();
    var ystimer = setInterval(function () {
        //每次按比例批处理，老版
        // if (shines.length > 0) {
        //     shines.forEach((inx) => {
        //         buildingjson.features[inx].properties['ftcolor'] = '#CCCCFF';
        //     })
        //     shines = [];
        // }
        // for (let i = 0, l = buildingjson.features.length / 10; i < l; i++) {
        //     let inx = Math.floor(Math.random() * regionsData.length);
        //     shines.push(inx)
        //     buildingjson.features[inx].properties['ftcolor'] = colors[Math.floor(Math.random() * 3)];
        // }

        //随机版
        // if (shines.length > 0) {
        //     shines.forEach((inx) => {
        //         map.setFeatureState({
        //             id: inx,
        //             source: 'buildings',
        //             'sourceLayer': 'jiningbuildings-7kbdau'
        //         }, { cc: colors[2] });
        //     })
        //     shines = [];
        // }
        // for (let i = 0, l = curfts.length / 80; i < l; i++) {
        //     let inx = Math.floor(Math.random() * curfts.length);
        //     shines.push(curfts[inx].id)
        //     map.setFeatureState({
        //         id: curfts[inx].id,
        //         source: 'buildings',
        //         'sourceLayer': 'jiningbuildings-7kbdau'
        //     }, { cc: colors[Math.floor(Math.random() * 3)] });
        // }

        //闪烁版
        shines.forEach(function (id) {
            var state = map.getFeatureState({
                id: id,
                source: 'buildings',
                'sourceLayer': 'jiningbuildings-7kbdau'
            });
            state.delay += 1;
            if (state.shine) {
                if (state.delay > 4) {
                    state.delay = 0;
                    state.shine = false;
                    // state.cc = colors[2];
                }
            }
            else {
                if (state.delay > 2) {
                    state.delay = 0;
                    state.shine = true;
                    // state.cc = colors[Math.floor(Math.random() * 2)];
                }
            }
            map.setFeatureState({
                id: id,
                source: 'buildings',
                'sourceLayer': 'jiningbuildings-7kbdau'
            }, state);
        })
    }, 200);
}

var curfts = [];
map.on('data', '3dbuildings', function () {
    // curfts = map.queryRenderedFeatures('buildings');
});

function initShine() {
    shines = [];
    var maxid = 10000;
    for (let i = 0, l = maxid / 20; i < l; i++) {
        let inx = Math.floor(Math.random() * maxid);
        shines.push(inx);
        map.setFeatureState({
            id: inx,
            source: 'buildings',
            'sourceLayer': 'jiningbuildings-7kbdau'
        }, {
            cc: colors[Math.floor(Math.random() * 2)],
            delay: Math.floor(Math.random() * 4),
            shine: true
        });
    }
}

function lnglatToLocal(lnglat,height){
    var pt = lnglatToMector(lnglat,height);
    // console.log(pt);
    return {
        x:(pt.x-mbpt.x)/threescale,
        y:(pt.y-mbpt.y)/threescale,
        z:height
    }
}

function flatten(arr) {
    while (arr.some((item) => Array.isArray(item))) {
      arr = [].concat.apply([], arr)
    }
    return arr
  }
  